Review-queue nav slices render auto-derived columns without the verdict field — declare highlightFields on ats_employer and ats_job - #71
Conversation
…ects `platform.nav.ts` and `seeker.nav.ts` mount three review/self queues as `filters` slices on the bare data surface. That surface never reads an object's authored list — objectui's `defaultColumnsFromObject` takes `highlightFields` when the object declares it, else walks the first six business fields — so authoring `ats_employer.all` / `ats_job.all` in #3 could not, and did not, change what those queues show. Declare the ADR-0085 role on `ats_employer`, `ats_job` and `ats_candidate` (spec 17; `compactLayout` was renamed to `highlightFields` in 11.7.0). Measured in a real boot, the three slices go from Employer Name · Short Name · Logo · Industry · Company Size · City Job Title · Employer · Employer Organization · Department · Description · Requirements Full Name · Account · Photo · Phone · Email · City to Employer Name · Industry · City · Verification · Service Tier · Primary Contact Job Title · Employer · Status · City · Employment Type · Work Mode Full Name · Current Title · City · Seeking Status · Years of Experience · Profile Visibility `ats_candidate` is the third instance recorded in the card's comment: the seeker's "My Profile" entry is a `filters` slice for the same reason. `ats_job` takes `work_mode` where the card proposed `published_at`: the status state machine only reaches `published` through `pending_review`, so `published_at` is null on every row the Jobs Pending queue can contain (0 of 6 pending; 0 of the 12 draft/pending_review/rejected rows). It would have been a permanently empty column in the one surface this card exists to fix. The rest of the proposal measured out and is used as written. Authored views are unaffected — `ats_employer.all`, `ats_job.all`, `ats_job.published` and `ats_inquiry.inbox` render their authored column arrays unchanged. Before/after shots for every surface, including the record headers and the employer's Jobs related list, are in docs/evidence/issue-33/. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PbJ5Cy9KDAzeQHo8bsMadG
Review — I reproduced the before and the after myself, on the tree this will merge intoThe card exists because #3 already shipped a fix that turned out to be a no-op on this surface (authoring
The BEFORE reproduces Non-regression on the authored views — checked, not assumed
Identical, 12 and 40 rows both sides. Your two deviations from the card, both measured out of the artifact
Every field name in all three lists exists on its object (I checked each against Merged against current
|
|
Routed, as promised: objectui#8413. It turned out to be worth filing rather than "too thin". The help string is wrong in both locales and in a direction that quietly costs authors something: Someone who trusts that help writes four fields and gets a worse default than the platform would have given them, with nothing reporting a problem — the reverse of the usual doc bug, where the code is stricter than the doc and something eventually errors. Your measurement is what surfaced it. Generated by Claude Code |
Fixes #33
What changed
Three
highlightFieldsdeclarations, nothing else —src/objects/employer.object.ts,job.object.ts,candidate.object.ts, plusdocs/evidence/issue-33/.platform.nav.tsandseeker.nav.tsmount three queues asfiltersslices on the bare datasurface. objectui's
ObjectDataPagecallsdefaultColumnsFromObject, which takeshighlightFieldswhen the object declares it and otherwise walks the first six business fields.It never consults an object's authored list — which is why authoring
ats_employer.allandats_job.allin #3 did not move these queues, exactly as the card predicted.The card's comment adds a third object: the seeker's My Profile entry is a
filtersslice(
{ user: '{current_user_id}' }) onats_candidatefor the same reason. Re-audited on thisbranch: those three are the only
filtersentries in the app's navigation; every other entrynames a view or lands on a declared list.
Measured, not expected
Booted twice in the same container on the same recipe — once on
62e496d(origin/main, thisbranch's base) for the "before", once on this branch for the "after". Reproduced rather than
quoted from the
docs/evidence/issue-3/shots; the reproduction matches them exactly. Personaadmin@platform.example, andcandidate01@mail.examplefor the seeker slice. Boot was--database-driver memorybecause #39 empties the Employers Pending queue on sqlite.The nav slices — the acceptance
Employer Name · Short Name · Logo · Industry · Company Size · CityEmployer Name · Industry · City · Verification · Service Tier · Primary ContactJob Title · Employer · Employer Organization · Department · Description · RequirementsJob Title · Employer · Status · City · Employment Type · Work ModeFull Name · Account · Photo · Phone · Email · CityFull Name · Current Title · City · Seeking Status · Years of Experience · Profile VisibilityThe declaration is not a no-op on this surface. Shots
00-…through05-…; both platformslices were reached by clicking the nav entry, not by typing the URL.
The other surfaces
highlightFieldsfeedsPrimary Contact · IndustryIndustry · City · Verification · Service Tier · Primary ContactJob Title · Employment Type · Work Mode · Salary Period · Min. Education · StatusJob Title · Status · City · Employment Type · Work ModeSalary Period(a unit with no amount beside it) andMin. Education, promotesStatus.Employeris in the set but is correctly suppressed on its own parent's related list.Employer · Employer OrganizationEmployer · Status · City · Employment Type · Work ModePhone · EmailCurrent Title · City · Seeking Status · Years of Experience · Profile VisibilityThe job record header is the one place this is not a clean win. At five strip items two badges
truncate to
Pendi…andFull-ti…, andStatusis now shown twice — once in the strip and oncein the state-machine stage bar immediately below it. The strip divides its width evenly, so this is
content-length behaviour rather than anything the metadata sets. Dropping
statusfromats_job.highlightFieldswould clear it and would also undo the card: a missingstatusin theJobs Pending queue is the defect being repaired. Kept, cost reported. Shot
09-….The candidate record header loses
PhoneandEmail. Both remain on the Details tab as livetel:/mailto:links. Net better in our reading — the header now answers "who is thisprofessionally, and are they looking" instead of showing two fields that field-level security masks
from every recruiter anyway — but it is a real removal, so it is stated rather than buried. Shot
11-….Non-regression
highlightFieldsfeeds only surfaces that derive their columns. Checked, and each rendered set isidentical to the array in
src/views/:ats_employer.all(columns),ats_job.all(
platformColumns),ats_job.published(seekerColumns),ats_inquiry.inbox. Shots12-…and
13-….One deviation from the card's proposal
ats_jobtakeswork_modewhere the card proposedpublished_at.The
job_status_transitionsstate machine only reachespublishedthroughpending_review, so arow in the Jobs Pending queue has never been published and its
published_atis null byconstruction. Measured on the seed: 0 of the 6 pending rows carry it, and 0 of the 12 rows in
draft/pending_review/rejected; the 28 that carry it are exactly thepublished/paused/closedrows. As proposed it would have been a permanently empty sixthcolumn in the one surface this card exists to repair.
work_modeis set on 40 of 40 jobs andcompletes the terms pair a reviewer checks alongside
employment_type.published_atkeeps itsplace on the record's Details tab and in the authored
ats_job.allview.The substitution also lands the set on the authored platform list:
ats_job.platformColumnsistitle · employer · status · city · employment_type · published_at · expires_at, and the declaredset is now its first five plus
work_mode. Same forats_employer, whose declared set is theauthored
columnsarray minussize. The queues now agree with the lists #3 authored.Everything else in the proposal measured out and is used as written, in the proposed order. Two
proposed-adjacent fields were checked and deliberately left out:
ats_employer.verification_docs(the card lists it as missing but does not propose it — the seed carries it on 0 of 12 rows and a
multi-file cell cannot be read at a glance; the reviewer opens it on the record), and
size, whichthe auto-derived set already had and the authored list keeps.
Every field name in all three declarations was confirmed against the object before use.
defaultColumnsFromObjectfilters the curated array throughobjectDef.fields[name], so amisspelling would have silently shrunk the column set rather than failing any gate.
Caveats worth a reviewer's eye
Employers Pending shows
Pendingon both rows and Jobs Pending showsPending Reviewon all six.Its value is that the queue now states which verdict state it is showing, and that the same set
carries real variance on the unfiltered list, the record header and the related list.
profile_visibilityonats_candidateis now legible to anyone who can already read the row.It is still enforced nowhere — that is Employers cannot read any candidate, and
profile_visibilityis enforced nowhere #13's subject, and nothing here should be read as changingit. Called out in the card's comment and repeated in the source comment.
Gates
Exit codes captured before any pipe, on the committed tree.
validateandlinteach report the same 3 pre-existing approval-staffing suggestions that62e496dreports; no new diagnostic. No new translatable string is introduced — the declarationsreference existing field keys, whose labels already ship in both
enandzh-CN.highlightFieldsindist/objectstack.jsonafter the build:Out of scope, filed separately
#67 —
Field.usercolumns render the raw user id in every grid, soPrimary Contactreadsusr_ats_pixelforge_admin. Visible in these shots but not caused here: the authoredats_employer.allview in shot12-…, which this branch does not touch, renders it identically.Unassigned and unlabelled for triage.
Generated by Claude Code